﻿using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;
using System.Linq;
using ESoft.Elasticsearch;
using ESoft.Locking;
using ESoft.Redis;
using ESoft.Specification;


namespace Test01
{
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder()
               .SetBasePath(AppContext.BaseDirectory)
               .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
               .AddEnvironmentVariables();
            var configuration = builder.Build();
            var services = new ServiceCollection();
            services.AddSingleton<IConfiguration>(configuration);
            services.AddRedis("127.0.0.1:6379");
            services.AddRedisLock();
            services.Configure<ElasticOptions>(configuration.GetSection("ElasticSearchContext"));
            services.AddSingleton<IEsService, EsService>();
            services.AddMemoryCache();
            IServiceProvider provider = services.BuildServiceProvider();


            var esService = provider.GetService<IEsService>();
           // var t = esService.CreateIndexAsync("test1").Result;

      //      var resaulst = esService.InsertDocumentAsync("test1", "_doc", new Test1 { name = "123" }).Result;
      //      Console.WriteLine(resaulst);
            //  var result = esService.SearchAsync("test1", "_doc").Result;
           // Console.WriteLine(result);
            //esService.SetModelValue
            //  var distributeLock = provider.GetService<IDistributeLock>();



            //var restStock = 100;
            //Parallel.For(0, 10, (i) =>
            //{
            //    //var restS = restStock;
            //    //Console.WriteLine($"进锁前，{i}剩余库存：" + restStock);

            //    ////distributeLock.AcquireLock("k");
            //    //Console.WriteLine($"进锁后扣减前，{i}剩余库存：" + restS);
            //    //if (restS > 0)
            //    //{
            //    //    restS -= 1;
            //    //    restStock = restS;
            //    //}
            //    //Console.WriteLine($"进锁后扣减后，{i}剩余库存：" + restStock);
            //    ////  distributeLock.ReleaseLock("k");
            //    //Console.WriteLine($"出锁后扣减后，{i}剩余库存：" + restStock);

            //    ThreadPool.QueueUserWorkItem(new WaitCallback((target) =>
            //    {
            //        Console.WriteLine($"进锁前，{i}剩余库存：" + restStock);
            //        distributeLock.AcquireLock("k");
            //        var restS = restStock;

            //        Console.WriteLine($"进锁后扣减前，{i}剩余库存：" + restS);
            //        if (restS > 0)
            //        {
            //            restS -= 1;
            //            restStock = restS;
            //        }
            //        Console.WriteLine($"进锁后扣减后，{i}剩余库存：" + restStock);
            //        distributeLock.ReleaseLock("k");
            //        Console.WriteLine($"出锁后扣减后，{i}剩余库存：" + restStock);
            //    }));
            //});
            ////Console.WriteLine($"剩余库存：" + restStock);
            Console.ReadKey();
        }

        public class Test1 { public string name { get; set; } }

        public static void Demo1()
        {
            var items = Enumerable.Range(-5, 10);
            Console.WriteLine("产生的数组为：{0}", string.Join(",  ", items.ToArray()));
            ISpecification<int> evenSpec = new EvenSpecification();
            // 获得一个组合规约
            var compositeSpecification = GetCompositeSpecification(evenSpec);
            // 类似Where(it=>it%2==0 && it > 0)
            // 前者是把两个条件合并写死成一个条件，而后者是将其组合成一个新条件。就如拼图出一架飞机和直接制造一个飞机模型概念是完全不同的
            foreach (var item in items.Where(it => compositeSpecification.IsSatisfiedBy(it)))
            {
                // 输出既是正数又是偶数的数
                Console.WriteLine(item);
            }
        }
        private static ISpecification<int> GetCompositeSpecification(ISpecification<int> spec)
        {
            ISpecification<int> plusSpec = new PlusSpecification();
            return spec.And(plusSpec);
        }

        //public static void TestThreadPool(object state)
        //{
        //    int workerThreads = 0;
        //    int completionPortThreads = 0;
        //    System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);

        //    Console.WriteLine(DateTime.Now.ToString() + "----workerThreads=" + workerThreads + "----completionPortThreads=" + completionPortThreads);
        //}
    }
}
